package com.javacoo.event.client.support;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.aop.support.AopUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 事件注册基类
 * <p>说明:</p>
 * <li></li>
 *
 * @author duanyong@jccfc.com
 * @date 2021/10/20 22:02
 */
@Slf4j
public class BaseEventRegister {
    /**
     * 获取所有注解 类
     * <p>说明:</p>
     * <li>在所有注解 org.springframework.stereotype.Service 类中查找方法包含指定注解</li>
     * @author duanyong@jccfc.com
     * @param annClass 类注解class
     * @param mAnnClass 方法注解class
     * @date 2021/10/20 22:02
     * @retuen Set<EventMetaData>
     */
    protected Set<EventMetaData> getEventMetaDatas(Class<? extends Annotation> annClass,Class<? extends Annotation> mAnnClass){
        //查找Service
        Map<String, Object> serviceMap = ApplicationContextProvider.getApplicationContext().getBeansWithAnnotation(annClass);
        log.info("事件注册数量:{},对象:{}",serviceMap.size(),serviceMap);
        Set<EventMetaData> eventMetaDatas = new HashSet<>();
        for (Map.Entry<String, Object> entry : serviceMap.entrySet()) {
            Class entryClass = AopUtils.getTargetClass(entry.getValue());
            //获取注解所在方法 public方法
            List<Method> methods = Arrays.stream(entryClass.getDeclaredMethods())
                    .filter(method -> Modifier.isPublic(method.getModifiers()))//获取本类 public方法
                    .filter(method->method.isAnnotationPresent(mAnnClass))//找到注解所在方法
                    .collect(Collectors.toList());
            if(methods.isEmpty()){
                continue;
            }
            eventMetaDatas.add(EventMetaData.builder().beanName(entry.getKey()).targetMethods(methods).targetClass(entryClass).build());
        }
        return eventMetaDatas;
    }
}
